package com.thinkverse.search.util;

import co.elastic.clients.elasticsearch.ElasticsearchClient;
import co.elastic.clients.elasticsearch.indices.CreateIndexRequest;
import co.elastic.clients.elasticsearch.indices.ExistsRequest;
import com.thinkverse.search.constant.ElasticsearchConstants;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;

/**
 * Elasticsearch索引初始化工具
 * 在应用启动时自动创建索引（如果不存在）
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class ElasticsearchIndexUtil implements CommandLineRunner {
    
    private final ElasticsearchClient elasticsearchClient;
    
    @Override
    public void run(String... args) throws Exception {
        try {
            createPaperIndex();
            createExpertIndex();
        } catch (Exception e) {
            log.error("索引初始化失败", e);
        }
    }
    
    /**
     * 创建论文索引
     */
    private void createPaperIndex() {
        try {
            boolean exists = elasticsearchClient.indices().exists(
                ExistsRequest.of(e -> e.index(ElasticsearchConstants.PAPER_INDEX))
            ).value();
            
            if (!exists) {
                CreateIndexRequest createIndexRequest = CreateIndexRequest.of(i -> i
                    .index(ElasticsearchConstants.PAPER_INDEX)
                    .mappings(m -> m
                        .properties("id", p -> p.long_(l -> l))
                        .properties("title", p -> p
                            .text(t -> t
                                .analyzer("standard")
                                .searchAnalyzer("standard")
                                .fields("keyword", f -> f.keyword(k -> k))
                            )
                        )
                        .properties("abstractText", p -> p
                            .text(t -> t
                                .analyzer("standard")
                                .searchAnalyzer("standard")
                            )
                        )
                        .properties("keywords", p -> p
                            .text(t -> t
                                .analyzer("standard")
                                .searchAnalyzer("standard")
                            )
                        )
                        .properties("authors", p -> p
                            .text(t -> t
                                .analyzer("standard")
                                .searchAnalyzer("standard")
                            )
                        )
                        .properties("firstAuthor", p -> p.keyword(k -> k))
                        .properties("correspondingAuthor", p -> p.keyword(k -> k))
                        .properties("journal", p -> p
                            .text(t -> t
                                .analyzer("standard")
                                .searchAnalyzer("standard")
                            )
                        )
                        .properties("publishYear", p -> p.integer(intProp -> intProp))
                        .properties("volume", p -> p.keyword(k -> k))
                        .properties("issue", p -> p.keyword(k -> k))
                        .properties("pages", p -> p.keyword(k -> k))
                        .properties("doi", p -> p.keyword(k -> k))
                        .properties("paperType", p -> p.keyword(k -> k))
                        .properties("status", p -> p.keyword(k -> k))
                        .properties("fileUrl", p -> p.keyword(k -> k))
                        .properties("fileSize", p -> p.long_(l -> l))
                        .properties("fileType", p -> p.keyword(k -> k))
                        .properties("downloadCount", p -> p.integer(intProp -> intProp))
                        .properties("citationCount", p -> p.integer(intProp -> intProp))
                        .properties("researchField", p -> p.keyword(k -> k))
                        .properties("rating", p -> p.integer(intProp -> intProp))
                        .properties("createTime", p -> p.date(d -> d))
                        .properties("updateTime", p -> p.date(d -> d))
                    )
                );
                
                elasticsearchClient.indices().create(createIndexRequest);
                log.info("论文索引创建成功: {}", ElasticsearchConstants.PAPER_INDEX);
            } else {
                log.info("论文索引已存在: {}", ElasticsearchConstants.PAPER_INDEX);
            }
        } catch (Exception e) {
            log.error("创建论文索引失败: {}", ElasticsearchConstants.PAPER_INDEX, e);
        }
    }
    
    /**
     * 创建专家索引
     */
    private void createExpertIndex() {
        try {
            boolean exists = elasticsearchClient.indices().exists(
                ExistsRequest.of(e -> e.index(ElasticsearchConstants.EXPERT_INDEX))
            ).value();
            
            if (!exists) {
                CreateIndexRequest createIndexRequest = CreateIndexRequest.of(i -> i
                    .index(ElasticsearchConstants.EXPERT_INDEX)
                    .mappings(m -> m
                        .properties("id", p -> p.long_(l -> l))
                        .properties("expertId", p -> p.long_(l -> l))
                        .properties("expertName", p -> p
                            .text(t -> t
                                .analyzer("standard")
                                .searchAnalyzer("standard")
                            )
                        )
                        .properties("researchFields", p -> p
                            .text(t -> t
                                .analyzer("standard")
                                .searchAnalyzer("standard")
                            )
                        )
                        .properties("expertiseTags", p -> p
                            .text(t -> t
                                .analyzer("standard")
                                .searchAnalyzer("standard")
                            )
                        )
                        .properties("influenceIndex", p -> p.double_(d -> d))
                        .properties("hIndex", p -> p.integer(intProp -> intProp))
                        .properties("paperCount", p -> p.integer(intProp -> intProp))
                        .properties("citationCount", p -> p.integer(intProp -> intProp))
                        .properties("collaborators", p -> p
                            .text(t -> t
                                .analyzer("standard")
                                .searchAnalyzer("standard")
                            )
                        )
                        .properties("organization", p -> p
                            .text(t -> t
                                .analyzer("standard")
                                .searchAnalyzer("standard")
                            )
                        )
                        .properties("position", p -> p.keyword(k -> k))
                        .properties("education", p -> p.text(t -> t))
                        .properties("researchDescription", p -> p
                            .text(t -> t
                                .analyzer("standard")
                                .searchAnalyzer("standard")
                            )
                        )
                        .properties("bio", p -> p
                            .text(t -> t
                                .analyzer("standard")
                                .searchAnalyzer("standard")
                            )
                        )
                        .properties("avatar", p -> p.keyword(k -> k))
                        .properties("contact", p -> p.keyword(k -> k))
                        .properties("homepage", p -> p.keyword(k -> k))
                        .properties("createTime", p -> p.date(d -> d))
                        .properties("updateTime", p -> p.date(d -> d))
                    )
                );
                
                elasticsearchClient.indices().create(createIndexRequest);
                log.info("专家索引创建成功: {}", ElasticsearchConstants.EXPERT_INDEX);
            } else {
                log.info("专家索引已存在: {}", ElasticsearchConstants.EXPERT_INDEX);
            }
        } catch (Exception e) {
            log.error("创建专家索引失败: {}", ElasticsearchConstants.EXPERT_INDEX, e);
        }
    }
}

